import { create } from 'zustand'
import { persist } from 'zustand/middleware'
import { Component } from '../types'
import { getComponentById } from '../utils'

interface State {
  components: Component[]
  curComponentId?: number | null
  curComponent: Component | null
  mode: 'edit' | 'preview'
}

interface Action {
  /**
   * 添加组件
   * @param component 组件属性
   * @param parentId 上级组件id
   * @returns
   */
  addComponent: (component: Component, parentId?: number) => void
  /**
   * 设置当前组件id
   * @param componentId 当前组件id
   * @returns
   */
  setCurComponentId: (componentId: number | null) => void

  /**
   * 更新组件属性
   * @param componentId 组件id
   * @param props 新组件属性
   * @returns
   */
  updateComponentProps: (componentId: number, props: any) => void

  /**
   * 设置模式
   * @param mode 模式
   * @returns
   */
  setMode: (mode: State['mode']) => void

  /**
   * 删除组件
   * @param componentId 组件id
   * @returns
   */
  deleteComponent: (componentId?: number | null) => void
}

export const useLowCodeStore = create<State & Action>()(
  persist(
    (set, get) => ({
      components: [],
      curComponent: null,
      mode: 'edit',
      addComponent: (component, parentId) =>
        set((state) => {
          // 如果有上级id，把当前组件添加到父组件的子组件中
          if (parentId) {
            // 通过父id递归查找父组件
            const parentComponent = getComponentById(parentId, state.components)

            if (parentComponent) {
              if (parentComponent?.children) {
                parentComponent?.children?.push(component)
              } else {
                parentComponent.children = [component]
              }
            }

            component.parentId = parentId
            return { components: [...state.components] }
          }
          return { components: [...state.components, component] }
        }),

      setCurComponentId: (componentId) =>
        set((state) => ({
          curComponentId: componentId,
          curComponent: getComponentById(componentId, state.components)
        })),

      updateComponentProps: (componentId, props) =>
        set((state) => {
          const component = getComponentById(componentId, state.components)
          if (component) {
            component.props = { ...component.props, ...props }

            if (componentId === state.curComponentId) {
              return {
                curComponent: component,
                components: [...state.components]
              }
            }

            return { components: [...state.components] }
          }

          return { components: [...state.components] }
        }),

      setMode: (mode) => set({ mode }),
      deleteComponent: (componentId) => {
        if (!componentId) return

        const component = getComponentById(componentId, get().components)
        if (component?.parentId) {
          const parentComponent = getComponentById(component.parentId, get().components)

          if (parentComponent) {
            parentComponent.children = parentComponent?.children?.filter((item) => item.id !== +componentId)

            set({ components: [...get().components] })
          }
        }
      }
    }),
    {
      name: 'lowCodeStore'
    }
  )
)
